/**
 * This file is part of the CAKIS project.
 * 
 * Copyright (c) 2009-2010 - Florian Arndt, Christian Kerl
 * 
 * @license GNU Lesser General Public License v3 <http://www.opensource.org/licenses/lgpl-3.0.html>
 * @since   01.03.2010
 * @version SVN: $Id: RecipeHome.java 149 2010-05-15 22:50:34Z christian-kerl@web.de $
 */

package org.cakis.server.action.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.cakis.server.model.Recipe;
import org.cakis.server.model.RecipeIngredient;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.Factory;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.datamodel.DataModel;
import org.jboss.seam.annotations.datamodel.DataModelSelection;
import org.jboss.seam.annotations.web.RequestParameter;
import org.jboss.seam.framework.EntityHome;
import org.jboss.seam.log.Log;

@Name("recipeHome")
@Scope(ScopeType.CONVERSATION)
public class RecipeHome extends EntityHome<Recipe> {
    private static final long serialVersionUID = 1L;

    @Logger
    private Log log;

    @RequestParameter
    private Long recipeId;

    @In(required=false, scope=ScopeType.CONVERSATION)
    private Recipe recipeImportResult;

    @DataModelSelection
    private RecipeIngredient selectedRecipeIngredient;

    @Out(required = false)
    private RecipeIngredient toEditRecipeIngredient;

    private List<RecipeIngredient> toDeleteRecipeIngredients = new ArrayList<RecipeIngredient>();

    private RecipeIngredient newIngredient;

    @Override
    public Object getId()
    {
        if (recipeId == null)
        {
            return super.getId();
        }
        else
        {
            return recipeId;
        }
    }

    @DataModel
    @Factory
    public List<RecipeIngredient> getIngredients() {
        if(instance != null) {
            List<RecipeIngredient> result = new ArrayList<RecipeIngredient>();
            result.addAll(instance.getIngredients());
            if(newIngredient != null) {
                result.add(newIngredient);
            }
            return result;
        } else {
            return null;
        }
    }

    @Override @Begin(join=true)
    public void create() {
        super.create();
    }

    @Override
    protected Recipe createInstance() {
        Recipe result;

        if(recipeImportResult != null) {
            result = recipeImportResult;

            for(RecipeIngredient ingredient : result.getIngredients()) {
                ingredient.setProduct(reattach(ingredient.getProduct()));

                if(ingredient.getQuantity().getUnit() != null) {
                    ingredient.getQuantity().setUnit(reattach(ingredient.getQuantity().getUnit()));
                }
            }
        } else {
            result = super.createInstance();
        }

        return result;
    }

    @Override
    public String persist() {
        endEdit();

        instance.setUuid(UUID.randomUUID());
        toDeleteRecipeIngredients.clear();

        return super.persist();
    }

    @Override
    public String update() {
        endEdit();

        for(RecipeIngredient ingredient : toDeleteRecipeIngredients) {
            getEntityManager().remove(reattach(ingredient));
        }
        toDeleteRecipeIngredients.clear();

        return super.update();
    }

    public void addRecipeIngredient() {
        resetNewIngredient();

        newIngredient = new RecipeIngredient();
        newIngredient.getQuantity().setNumberOfPieces(0.0f);
        newIngredient.getQuantity().setQuantity(0.0f);

        beginEdit(newIngredient);
    }

    public void editRecipeIngredient() {
        resetNewIngredient();

        beginEdit(selectedRecipeIngredient);
    }

    public void deleteRecipeIngredient() {
        if(selectedRecipeIngredient.getId() != null) {
            toDeleteRecipeIngredients.add(selectedRecipeIngredient);
        }
        instance.getIngredients().remove(selectedRecipeIngredient);
    }

    public void saveEditRecipeIngredient() {
        if(newIngredient != null) {
            newIngredient.setRecipe(instance);
            instance.getIngredients().add(newIngredient);
        }
        endEdit();
    }

    public void cancelEditRecipeIngredient() {
        endEdit();
    }

    private void beginEdit(RecipeIngredient ingredient) {
        toEditRecipeIngredient = ingredient;
    }

    private void endEdit() {
        resetNewIngredient();
        toEditRecipeIngredient = null;
    }

    private void resetNewIngredient() {
        newIngredient = null;
    }

    private <T> T reattach(T object) {
        return getEntityManager().merge(object);
    }
}
